const fs = require('fs')
const path = require('path')

// 处理输入的组件名称，将大写字母前添加 -，去除开头的 -，将下划线替换为 -，最后将所有字母转换为小写
function processName(inputName) {
  let name = inputName.replace(/([A-Z])/g, '-$1')
  name = name.replace(/^-/, '')
  name = name.replace(/_/g, '-')
  return name.toLowerCase()
}

// 验证输入的参数是否合法
function validateInput(name) {
  if (process.argv.length !== 3 || /\s/.test(name) || name === '') {
    console.log('Usage: node script_name.js ${name} with no space')
    process.exit(1)
  }
}

// 检查目录是否已经存在
function checkDirectoryExists(dirname) {
  if (fs.existsSync(dirname)) {
    console.log(`${dirname} component already exists, please change it`)
    process.exit(1)
  }
}

// 将每个单词的首字母大写，其余字母小写，并且去除 -
function furtherProcessName(name) {
  const parts = name.split('-')
  const newParts = parts.map(part => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase())
  return newParts.join('')
}

// 生成 PROP_NAME，将 NAME 的首字母转换为小写，其余部分保持不变
function generatePropName(name) {
  return name.charAt(0).toLowerCase() + name.slice(1)
}

// 创建目录
function createDirectories(dirname) {
  fs.mkdirSync(path.join(dirname, 'src'), { recursive: true })
  fs.mkdirSync(path.join(dirname, 'style'), { recursive: true })
}

// 创建文件
function createFiles(dirname, inputName, name, propName, filePath) {
  // 创建 $DIRNAME/src/$INPUT_NAME.vue 文件
  const vueContent = `<template>
  <div>
    <slot />
  </div>
</template>

<script lang="ts" setup>
import { ${propName}Emits, ${propName}Props } from './${name}'

defineOptions({
  name: 'M${inputName}'
})

const props = defineProps(${propName}Props)
const emit = defineEmits(${propName}Emits)
</script>
`
  fs.writeFileSync(path.join(dirname, 'src', `${name}.vue`), vueContent)

  // 创建 $DIRNAME/src/$INPUT_NAME.ts 文件
  const tsContent = `import { buildProps } from '@page-com/components/utils/util'
import type ${inputName} from './${name}.vue'
import type { ExtractPropTypes } from 'vue'

export const ${propName}Props = buildProps({} as const)
export type ${inputName}Props = ExtractPropTypes<typeof ${propName}Props>

export type ${inputName}Instance = InstanceType<typeof ${inputName}>
export const ${propName}Emits = {}
export type ${inputName}Emits = typeof ${propName}Emits
`
  fs.writeFileSync(path.join(dirname, 'src', `${name}.ts`), tsContent)

  // 创建 $DIRNAME/index.ts 文件
  const indexContent = `import { withInstall } from '@page-com/components/utils/util'
import ${inputName} from './src/${name}.vue'
import type { SFCWithInstall } from '@page-com/components/types'

export const M${inputName}: SFCWithInstall<typeof ${inputName}> = withInstall(${inputName})
export default M${inputName}

export * from './src/${name}'
`
  fs.writeFileSync(path.join(dirname, 'index.ts'), indexContent)

  // 创建 $DIRNAME/style/index.ts 文件
  const styleIndexContent = `import '@page-com/components/base/style'
import '@page-com/theme-chalk/src/${name}.scss'
`
  fs.writeFileSync(path.join(dirname, 'style', 'index.ts'), styleIndexContent)

  // 创建 $DIRNAME/style/css.ts 文件
  const styleCssContent = `import '@page-com/components/base/style/css'
import '@page-com/theme-chalk/m-${name}.css'
`
  fs.writeFileSync(path.join(dirname, 'style', 'css.ts'), styleCssContent)

  // 创建 $FILE_PATH/theme-chalk/src/$INPUT_NAME.scss 文件
  fs.writeFileSync(path.join(filePath, 'theme-chalk', 'src', `${name}.scss`), '')
}

// 更新 index.ts 和 global.d.ts 文件
function updateIndexFiles(inputName, filePath, name) {
  // 更新 $FILE_PATH/components/index.ts 文件
  const indexTsPath = path.join(filePath, 'components', 'index.ts')
  fs.appendFileSync(indexTsPath, `export * from './${name}'\n`)

  // 获取 typings 目录的绝对路径
  const typePath = path.join(__dirname, '..', 'typings')
  const globalDtsPath = path.join(typePath, 'global.d.ts')
  fs.appendFileSync(globalDtsPath, `M${inputName}: typeof import('page-com')['M${inputName}']\n`)

  // 更新 $FILE_PATH/components/index.ts 文件
  const indexScssPath = path.join(filePath, 'theme-chalk', 'src', 'index.scss')
  fs.appendFileSync(indexScssPath, `@use './${name}.scss';\n`)
}

if (process.argv.length !== 3) {
  console.log('Usage: node script_name.js <component_name>')
  process.exit(1)
}

const inputName = process.argv[2]
let name = processName(inputName)
let uName = furtherProcessName(name)

validateInput(name)

const scriptDir = path.dirname(__filename)
const filePath = path.join(scriptDir, '..', 'packages')
const dirname = path.join(filePath, 'components', name)

checkDirectoryExists(dirname)

const propName = generatePropName(uName)

createDirectories(dirname)
createFiles(dirname, uName, name, propName, filePath)
updateIndexFiles(uName, filePath, name)
